package com.sitech.ibnms.c3p.command.script;

import com.sitech.ibnms.c3p.Application;
import com.sitech.ibnms.c3p.command.CommandType;
import com.sitech.ibnms.c3p.domain.ResourceAccount;
import com.sitech.ibnms.c3p.mappers.ResourceAccountMapper;
import com.sitech.ibnms.c3p.service.ScriptExecutor;
import com.sitech.ismp.messageObject.cc.CccpResults;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import request.ScriptRequest;

import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Map;

/**
 * Created by liujhc on 7/20.
 */
@Component
public class ScriptExecutorImpl implements ScriptExecutor {
    protected final Logger logger = LoggerFactory.getLogger(getClass());


    @Autowired
    private ResourceAccountMapper resourceAccountMapper;

    @Autowired
    AutowireCapableBeanFactory beanFactory;

    @Override
    public CccpResults executeScript(final ScriptRequest req) {
        Assert.notNull(req.getResourceId(), "resourceId must not be null");
        Assert.notNull(req.getContent(), "content must not be null");
        String requestId = generateRequestId();
        req.setRequestId(requestId);
        return executeScript(req, Collections.<String, String>emptyMap());
    }

    public CccpResults executeScript(final ScriptRequest req, final Map<String, String> context) {
        ResourceAccount resourceAccount = resourceAccountMapper.findById(req.getResourceId());
        logger.info("*******************resourceId="+req.getRequestId()+"***********");
        System.out.println("*******************resourceId="+req.getRequestId()+"***********");
        try {
            return executeScript(req, resourceAccount, context);
        } catch (Exception e) {
            throw Application.sneakyThrow(e);
        }
    }

    @Override
    public CccpResults executeScript(final ScriptRequest req, final ResourceAccount resourceAccount, Map<String, String> context) {
        try {
            Assert.notNull(resourceAccount, "no ResourceAccount found!");
            ScriptCommand command = (ScriptCommand) beanFactory.createBean(CommandType.SHELL.getBeanClass());
            CccpResults cccpResults = command.doExecuteScript(req, resourceAccount).get();
            if (context != null) cccpResults.getParams().putAll(context);
            return cccpResults;
        } catch (Exception e) {
            throw Application.sneakyThrow(e);
        }
    }
    public CccpResults executeSql(final ScriptRequest req, final ResourceAccount resourceAccount, Map<String, String> context) {
        try {
            Assert.notNull(resourceAccount, "no ResourceAccount found!");
            ScriptCommand command = (ScriptCommand) beanFactory.createBean(CommandType.SQL.getBeanClass());
            CccpResults cccpResults = command.doExecuteScript(req, resourceAccount).get();
            if (context != null) cccpResults.getParams().putAll(context);
            return cccpResults;
        } catch (Exception e) {
            throw Application.sneakyThrow(e);
        }
    }
    /**
     * 生成唯一的requestId
     *
     * @return
     */
    private static String generateRequestId() {
        byte[] arrayOfByte = new byte[2];
        new SecureRandom().nextBytes(arrayOfByte);
        StringBuilder str = new StringBuilder(arrayOfByte.length * 2);
        for (byte aByte : arrayOfByte) {
            str.append(String.format("%02x", aByte + 128));
        }
        return String.format("c3p%s.%s", new SimpleDateFormat("yyMMddHHmmss.SSS").format(new Date()), str);
    }
}
